﻿using Learun.Application.Organization;
using Learun.Util;
using Learun.Util.SqlSugar;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using static Learun.Application.TwoDevelopment.ZZDT_EC.ProjectSugar;
using static Learun.Util.SqlSugar.SqlSugarHelper;

namespace Learun.Application.TwoDevelopment.ZZDT_EC
{
    /// <summary>
    /// 版 本 PIT-ADMS V7.0.3 敏捷开发框架
    /// Copyright (c) 2013-2018 Hexagon PPM
    /// 创 建：超级管理员
    /// 日 期：2022-06-21 15:32
    /// 描 述：端子排表
    /// </summary>
    public class ec_PanelStripBLL : ec_PanelStripIBLL
    {
        ec_PanelStripService ec_PanelStripService;
        ec_WireTerminalService ec_WireTerminalService;
        ec_Wire_GroupService ec_Wire_GroupService;

        public ec_PanelStripBLL()
        {
            ec_PanelStripService = new ec_PanelStripService();
            ec_WireTerminalService = new ec_WireTerminalService();
            ec_Wire_GroupService = new ec_Wire_GroupService();
        }
        #region 获取数据
        /// <summary>
        /// 端子排
        /// </summary>
        /// <param name="queryJson"></param>
        /// <param name="pagination"></param>
        /// <param name="OnlySelf">默认true，只查询本表</param>
        /// <returns></returns>
        public IEnumerable<ec_PanelStripEntity> GetList(string queryJson, Pagination pagination = null, bool OnlySelf = true)
        {
            try
            {
                var queryParam = queryJson.ToJObject();
                string ProjectId = queryParam["ProjectId"]?.ToString();
                string PanelID = queryParam["PanelID"]?.ToString();
                string StripName = queryParam["StripName"]?.ToString();

                var seft = queryParam["OnlySelf"]?.ToString();//query里有，那就覆盖
                if (!string.IsNullOrEmpty(seft))
                {
                    OnlySelf = bool.Parse(seft);
                }
                var tableName = TableName<ec_PanelStripEntity>(ProjectId);

                var query = Db.Queryable<ec_PanelStripEntity>().AS(tableName)
                    .WhereIF(!string.IsNullOrEmpty(PanelID), x => x.PanelID == PanelID)
                    .WhereIF(!string.IsNullOrEmpty(StripName), x => x.StripName == StripName);
                List<ec_PanelStripEntity> list;
                if (pagination == null)
                {
                    list = query.ToList();
                }
                else
                {
                    list = query.ToPageList(pagination.page, pagination.rows);
                }
                if (!OnlySelf)
                {
                    var channelTableName = TableName<ec_PanelChannelEntity>(ProjectId);
                    var termTableName = TableName<ec_PanelStripTermEntity>(ProjectId);

                    var ids = list.Select(x => x.StripID).ToList();
                    var channels = Db.Queryable<ec_PanelChannelEntity>().AS(channelTableName)
                        .Where(x => ids.Contains(x.StripID)).ToList();

                    var channelIds = channels.Select(x => x.ChannelID).ToList();

                    var terms = Db.Queryable<ec_PanelStripTermEntity>().AS(termTableName)
                        .Where(x => channelIds.Contains(x.ChannelID)).ToList();
                    list.ForEach(x =>
                    {
                        x.Channels = channels.Where(y => y.StripID == x.StripID).ToList();
                        x.Channels.ForEach(y =>
                        {
                            y.Terms = terms.Where(z => z.ChannelID == y.ChannelID).ToList();
                        });
                    });
                }
                return list;
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowBusinessException(ex);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="StripID"></param>
        /// <param name="OnlyStrip">true时，只有端子排本身;false时，带上下面的通道和端子</param>
        /// <returns></returns>
        public ec_PanelStripEntity GetEntity(string ProjID, string StripID, bool OnlyStrip = false, bool HaveChannel = true)
        {
            //优化查询
            try
            {
                {
                    var users = new UserBLL().GetAllList();  //暂时都给权限

                    //var tableName = ProjectSugar.TableName<ec_PanelStripEntity>(ProjID);
                    //var res = SqlSugarHelper.Db.Queryable<ec_PanelStripEntity>().AS(tableName).First(x => x.StripID == StripID);
                    var res = ec_PanelStripService.GetEntity(ProjID, StripID);
                    if (res != null)
                    {
                        if (!OnlyStrip)
                        {
                            var channelTableName = ProjectSugar.TableName<ec_PanelChannelEntity>(ProjID);
                            var termTableName = ProjectSugar.TableName<ec_PanelStripTermEntity>(ProjID);
                            var TagTableName = ProjectSugar.TableName<ec_enginedataEntity>(ProjID);
                            var cableTableName = ProjectSugar.TableName<ec_CableEntity>(ProjID);
                            var conns = ec_WireTerminalService.GetList(("{ProjectId:\"" + ProjID + "\",PanelID:\"" + res.PanelID + "\",StripID:\"" + res.StripID + "\"}"));


                            if (HaveChannel)
                            {
                                res.Channels = SqlSugarHelper.Db.Queryable<ec_PanelChannelEntity>().AS(channelTableName).Where(x => x.StripID == StripID).ToList();
                                var channelIds = res.Channels.Select(x => x.ChannelID).ToList();
                                var terms = SqlSugarHelper.Db.Queryable<ec_PanelStripTermEntity>().AS(termTableName)
                                    .Where(x => x.StripID == StripID && channelIds.Contains(x.ChannelID)).ToList();

                                //var conns = ec_WireTerminalService.GetList(("{ProjectId:\"" + ProjID + "\",PanelID:\"" + res.PanelID + "\",StripID:\"" + res.StripID + "\"}"));

                                var signals = new ec_Wire_GroupBLL().GetList("{ProjectId:\"" + ProjID + "\",ChannelIDs:\"" + string.Join(",", channelIds) + "\"}");

                                var homerunCableIds = res.Channels.Select(x => x.HomerunCableId).ToList();
                                var cables = SqlSugarHelper.Db.Queryable<ec_CableEntity>().AS<ec_CableEntity>(cableTableName)
                                    .InnerJoin<ec_enginedataEntity>((a, b) => a.EngineerDataID == b.EngineDataID).AS<ec_enginedataEntity>(TagTableName)
                                    .Where((a, b) => homerunCableIds.Contains(a.CableID))
                                    .Select((a, b) => new { a.CableID, b.TagNumber }).ToList();
                                foreach (var Channel in res.Channels)
                                {
                                    if (string.IsNullOrEmpty(Channel.HomerunCableId))
                                    {
                                        #region 普通电缆情况，所以下面需要带出来端子和通道
                                        var Terms = terms.Where(x => x.ChannelID == Channel.ChannelID).ToList();
                                        foreach (ec_PanelStripTermEntity term in Terms)
                                        {
                                            var conn = conns.Where(x => x.TermID == term.TermID).ToList();
                                            if (conn.Count() > 1)
                                            {
                                                for (int i = 1; i < conn.Count(); i++)
                                                {
                                                    ec_WireTerminalService.DeleteEntity(ProjID, conn[i].ID, null);//多的都是有问题的记录
                                                }
                                                term.Connection = conn[0];
                                            }
                                            else if (conn.Count() == 1)
                                            {
                                                term.Connection = conn[0];
                                            }
                                            else
                                            {
                                                term.Connection = null;
                                            }

                                            if (term.Connection != null)
                                            {
                                                //Real user name
                                                term.Connection.CreateUserID = users.FirstOrDefault(x => x.F_UserId == term.Connection.CreateUserID || x.F_RealName == term.Connection.CreateUserID)?.F_RealName;
                                                term.Connection.UpdateUserID = users.FirstOrDefault(x => x.F_UserId == term.Connection.UpdateUserID || x.F_RealName == term.Connection.UpdateUserID)?.F_RealName;

                                                if (string.IsNullOrEmpty(term.Connection.UpdateUserID))
                                                {
                                                    term.Connection.UpdateUserID = term.Connection.CreateUserID;
                                                }

                                            }

                                        }

                                        Channel.Terms = Terms.ToList();
                                        Channel.Signal = signals.FirstOrDefault(x => x.ChannelID == Channel.ChannelID);
                                        #endregion
                                    }
                                    else
                                    {
                                        //母线
                                        var Terms = terms.Where(x => x.ChannelID == Channel.ChannelID).ToList();
                                        Channel.Terms = Terms.ToList();

                                        //var cable = SqlSugarHelper.Db.Queryable<ec_enginedataEntity>().AS(TagTableName)
                                        //    .InnerJoin<ec_CableEntity>((a, b) => a.EngineDataID == b.EngineerDataID).AS<ec_CableEntity>(cableTableName)
                                        //    .Where((a, b) => b.CableID == Channel.HomerunCableId)
                                        //    .First();
                                        var cable = cables.FirstOrDefault(x => x.CableID == Channel.HomerunCableId);
                                        if (cable != null)
                                        {
                                            Channel.HomerunCableName = cable.TagNumber;
                                        }
                                    }

                                }
                            }
                            else
                            {

                                var fakeCH = new ec_PanelChannelEntity
                                {
                                    ChannelID = "-1",
                                    HomerunCableId = "-1"
                                };
                                var terms = SqlSugarHelper.Db.Queryable<ec_PanelStripTermEntity>().AS(termTableName)
                                    .Where(x => x.StripID == StripID && x.ChannelID == "-1").OrderBy(x => x.Term_Seq).ToList();
                                foreach (var term in terms)
                                {
                                    term.Connection = conns.FirstOrDefault(x => x.TermID == term.TermID && x.Strip_Side == 0);
                                    term.Connection2 = conns.FirstOrDefault(x => x.TermID == term.TermID && x.Strip_Side == 1);
                                }
                                fakeCH.Terms = terms;
                                res.Channels = new List<ec_PanelChannelEntity>
                                {
                                    fakeCH
                                };



                            }
                        }
                    }

                    return res;
                }
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowBusinessException(ex);
                }
            }
        }
        #endregion
        #region 提交数据
        /// <summary>
        /// 删除实体数据
        /// <param name="keyValue">主键</param>
        /// <summary>
        /// <returns></returns>
        public void DeleteEntity(string ProjectId, string keyValue)
        {
            try
            {
                ec_PanelStripService.DeleteEntity(ProjectId, keyValue);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowBusinessException(ex);
                }
            }
        }
        /// <summary>
        /// 保存实体数据（新增、修改）
        /// <param name="keyValue">主键</param>
        /// <summary>
        /// <returns></returns>
        public void SaveEntity(string ProjectId, string StripID, ec_PanelStripEntity entity, out string NewStripID, bool haveCH = true)
        {
            NewStripID = "";
            if (entity != null)
            {
                ec_PanelStripService.SaveEntity(ProjectId, StripID, entity, out NewStripID);
                if (haveCH)
                {

                    var Channels = entity.Channels;
                    var chTableName = ProjectSugar.TableName<ec_PanelChannelEntity>(ProjectId);
                    var signalTableName = ProjectSugar.TableName<ec_Wire_GroupEntity>(ProjectId);
                    var existCHs = SqlSugarHelper.Db.Queryable<ec_PanelChannelEntity>().AS(chTableName).Where(x => x.StripID == entity.StripID).ToList();

                    if (Channels != null)
                    {
                        var homerunCableIds = Channels.Select(x => x.HomerunCableId).Distinct().ToList();
                        homerunCableIds.AddRange(existCHs?.Select(x => x.HomerunCableId).Distinct().ToList());
                        var signals = SqlSugarHelper.Db.Queryable<ec_Wire_GroupEntity>().AS(signalTableName)
                            .Where(x => homerunCableIds.Contains(x.CableId) && (x.Status == WireGroupStatusEnum.Used || x.Status == WireGroupStatusEnum.New))
                            .ToList();

                        var termTableName = ProjectSugar.TableName<ec_PanelStripTermEntity>(ProjectId);
                        var terms = new List<ec_PanelStripTermEntity>();
                        //Channel、Terms的保存搬出来
                        string stripId = NewStripID;
                        Channels.ForEach(x =>
                        {
                            var existCH = existCHs.FirstOrDefault(y => y.ChannelID == x.ChannelID);
                            if (existCH != null)
                            {
                                if (!string.IsNullOrEmpty(existCH.HomerunCableId) && string.IsNullOrEmpty(x.HomerunCableId))
                                {
                                    //取消了
                                    signals.Where(y => y.CableId == existCH.HomerunCableId && y.Status == WireGroupStatusEnum.Used).ToList().ForEach(y =>
                                    {
                                        y.Status = WireGroupStatusEnum.New;
                                    });
                                }
                                else if (string.IsNullOrEmpty(existCH.HomerunCableId) && !string.IsNullOrEmpty(x.HomerunCableId))
                                {
                                    //关联了
                                    signals.Where(y => y.CableId == x.HomerunCableId && y.Status == WireGroupStatusEnum.New).ToList().ForEach(y =>
                                    {
                                        y.Status = WireGroupStatusEnum.Used;
                                    });
                                }
                            }

                            //x.PanelID = entity.PanelID;
                            x.StripID = stripId;
                            if (string.IsNullOrEmpty(x.ChannelID))
                            {
                                x.Create();
                            }
                            else
                            {
                                x.Modify(x.ChannelID);
                            }
                            if (x.Terms != null)
                            {
                                x.Terms.ForEach(y =>
                                {
                                    //y.PanelID = x.PanelID;
                                    y.StripID = x.StripID;
                                    y.ChannelID = x.ChannelID;
                                    if (string.IsNullOrEmpty(y.TermID))
                                    {
                                        y.Create();
                                    }
                                    else
                                    {
                                        y.Modify(y.TermID);
                                    }
                                });
                                terms.AddRange(x.Terms);
                            }
                        });
                        SqlSugarHelper.Db.Updateable(signals).AS(signalTableName).ExecuteCommand();
                        var c = SqlSugarHelper.Db.Storageable(Channels).As(chTableName).ToStorage();
                        c.AsInsertable.ExecuteCommand();
                        c.AsUpdateable.IgnoreColumns(x => x.CreateTime).IgnoreColumns(x => x.CreateUserID).ExecuteCommand();
                        var t = SqlSugarHelper.Db.Storageable(terms).As(termTableName).ToStorage();
                        t.AsInsertable.ExecuteCommand();
                        t.AsUpdateable.IgnoreColumns(x => x.CreateTime).IgnoreColumns(x => x.CreateUserID).ExecuteCommand();
                    }
                }

                else
                {
                    var Channels = entity.Channels;
                    var chTableName = ProjectSugar.TableName<ec_PanelChannelEntity>(ProjectId);
                    var signalTableName = ProjectSugar.TableName<ec_Wire_GroupEntity>(ProjectId);

                    if (Channels != null && Channels.Count == 1)
                    {

                        var termTableName = ProjectSugar.TableName<ec_PanelStripTermEntity>(ProjectId);
                        var terms = new List<ec_PanelStripTermEntity>();
                        //Channel、Terms的保存搬出来
                        string stripId = NewStripID;
                        var fakeCH = Channels.First();

                        if (fakeCH.Terms != null)
                        {
                            fakeCH.Terms.ForEach(y =>
                            {
                                //y.PanelID = x.PanelID;
                                y.StripID = stripId;
                                y.ChannelID = "-1";
                                if (string.IsNullOrEmpty(y.TermID))
                                {
                                    y.Create();
                                }
                                else
                                {
                                    y.Modify(y.TermID);
                                }
                            });
                            terms.AddRange(fakeCH.Terms);
                        }
                        var t = SqlSugarHelper.Db.Storageable(terms).As(termTableName).ToStorage();
                        t.AsInsertable.ExecuteCommand();
                        t.AsUpdateable.IgnoreColumns(x => x.CreateTime).IgnoreColumns(x => x.CreateUserID).ExecuteCommand();
                    }
                }
            }
        }
        /// <summary>
        /// 调端子排所属Panel
        /// </summary>
        /// <param name="StripID">端子排ID</param>
        /// <param name="PanelID">PanelID</param>
        /// <param name="ProjectId">项目ID</param>
        public void SwitchPanelStrip(string StripID, string PanelID, string ProjectId)
        {
            try
            {
                ec_PanelStripService.SwitchPanelStrip(StripID, PanelID, ProjectId);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowBusinessException(ex);
                }
            }
        }
        #endregion

    }
}
